/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package beans;

import config.GestorVehiculos;
import config.Reloj;
import java.util.ArrayList;
import java.util.Calendar;
/**
 *
 * @author Shadow
 */
public class Vehiculo {
    private Punto _posicionInicial;
    private Punto _posicionActual;
    private Path _ruta;
    private double _consumoPorKm;
    private int _capacidadTotal;
    private int _capacidadActual;
    private int _velocidad;
    private double _gasolinaTotal;
    private double _gasolinaActual;
    private int _tipoVehiculo;
    public boolean disponible = true;
    private int _residuo = 0;
    private int _posEnRuta = 0;
    private int _costoxKm;
    private ArrayList<Pedido> _listaPedido;
    private String _placa;
    private int _costoHoraExtra;
    private Calendar finTurno;

    public int getCostoHoraExtra() {
        return _costoHoraExtra;
    }

    public void setCostoHoraExtra(int _costoHoraExtra) {
        this._costoHoraExtra = _costoHoraExtra;
    }

    public String getPlaca() {
        return _placa;
    }

    public void setPlaca(String _placa) {
        this._placa = _placa;
    }

    public ArrayList<Pedido> getListaPedido() {
        return _listaPedido;
    }

    public void setListaPedido(ArrayList<Pedido> _listaPedido) {
        this._listaPedido = _listaPedido;
    }
    public Vehiculo(Punto puntoIni){
        _posicionInicial = puntoIni;
        _posicionActual = puntoIni;
        _ruta = new Path(puntoIni);
    }

    public Punto getPosicionInicial() {
        return _posicionInicial;
    }

    public void setPosicionInicial(Punto _posicionInicial) {
        this._posicionInicial = _posicionInicial;
    }

    public Punto getPosicionActual() {
        return _posicionActual;
    }

    public void setPosicionActual(Punto _posicionActual) {
        this._posicionActual = _posicionActual;
    }
    public Path getRuta() {
        return _ruta;
    }
    public void setRuta(Path _ruta) {
        this._ruta = _ruta;
    }
    public void setRuta (ArrayList<Punto> ruta){
        this._posicionActual = ruta.get(0);
        this._posEnRuta = 0;
        this._ruta = new Path(ruta);
    }
    public void setRuta (Punto ruta){
        this._posicionActual = ruta;
        this._posEnRuta = 0;
        this._ruta = new Path(ruta);
    }
    public double getConsumoPorKm() {
        return _consumoPorKm;
    }
    public void setConsumoPorKm(double _consumoPorKm) {
        this._consumoPorKm = _consumoPorKm;
    }

    public int getCapacidadTotal() {
        return _capacidadTotal;
    }

    public void setCapacidadTotal(int _capacidadTotal) {
        this._capacidadTotal = _capacidadTotal;
    }

    public boolean isDisponible() {
        return disponible;
    }

    public void setDisponible(boolean disponible) {
        this.disponible = disponible;
    }

    public int getResiduo() {
        return _residuo;
    }

    public void setResiduo(int _residuo) {
        this._residuo = _residuo;
    }
    
    public int getCapacidadActual() {
        return _capacidadActual;
    }
    public void setCapacidadActual(int _capacidadActual) {
        this._capacidadActual = _capacidadActual;
    }
    public int getVelocidad() {
        return _velocidad;
    }
    public void setVelocidad(int _velocidad) {
        this._velocidad = _velocidad;
    }

    public double getGasolinaTotal() {
        return _gasolinaTotal;
    }

    public void setGasolinaTotal(double _gasolinaTotal) {
        this._gasolinaTotal = _gasolinaTotal;
    }
    double getGasolinaActual() {
        return _gasolinaActual;
    }
    public void setGasolinaActual(double _gasolinaActual) {
        this._gasolinaActual = _gasolinaActual;
    }

    public int getTipoVehiculo() {
        return _tipoVehiculo;
    }

    public void setTipoVehiculo(int _tipoVehiculo) {
        this._tipoVehiculo = _tipoVehiculo;
    }

    public void actualizaOrdenes(Punto p,ArrayList<Pedido> pedidos){
        Reloj reloj = Reloj.getInstancia();
        if(p == Mapa.getAlmacen()){
            _gasolinaActual = _gasolinaTotal;
            _capacidadActual = _capacidadTotal;
            
            int turnoR = reloj.getTurnoActual();
            
            if (turnoR != this.getTurno()){
                HoraExtra he = new HoraExtra(this);
                he.setFecha(reloj.getFecha());
                he.calcularHorasExtras();
                ArrayList<HoraExtra> listaHoraExtra = GestorVehiculos.getInstancia().getHorasExtras();
                
                listaHoraExtra.add(he);
                
                GestorVehiculos.getInstancia().setHorasExtras(listaHoraExtra);
            }
            
            return;
        }
        for(int i =0; i< _listaPedido.size();i++){
            Pedido pedido = _listaPedido.get(i);
            if(pedido.getDestino()==p){//punto del pedido igual al punto del vehiculo
                if(pedido.getDemanda() > this.getCapacidadActual()){//la capacidad del vehiculo es menor a la cantidad de paquetes del pedido
                    pedido.setDemanda(pedido.getDemanda()-this.getCapacidadActual());
                    this.setCapacidadActual(0);
                }
                else{
                    this.setCapacidadActual(this.getCapacidadActual()-pedido.getDemanda());
                    pedido.setDemanda(0);
                    _listaPedido.remove(pedido);
                    pedidos.remove(pedido);
                }
            }
        }
    }
	
    public void avanzar(int tiempo, ArrayList<Pedido> pedidos){
        float dist = _velocidad * tiempo/60;
        int numNodos = Math.round(dist);
        float residuo = dist - numNodos;
        _residuo += residuo;
        int nodoExtra= Math.round(_residuo);
        _residuo-=nodoExtra;
        numNodos+=nodoExtra;
        int posActual = _posEnRuta;
        int posFin = posActual+numNodos;
        for(int i = posActual; i< posFin && i<_ruta.size();i++){
            _posicionActual = _ruta.get(i);
            _posEnRuta++;
            actualizaOrdenes(_posicionActual,pedidos);
            this._gasolinaActual -= numNodos;
        }
        
    }

    public int getCostoxKm() {
        return _costoxKm;
    }

    public void setCostoxKm(int _costoxKm) {
        this._costoxKm = _costoxKm;
    }
        private int _id;

    public int getId() {
        return _id;
    }

    public void setId(int _id) {
        this._id = _id;
    }
    private int turno = 1;
    private int horaExtra = 0;

    public int getHoraExtra() {
        return horaExtra;
    }

    public void setHoraExtra(int horaExtra) {
        this.horaExtra = horaExtra;
    }

    public int getTurno() {
        return turno;
    }

    public void setTurno(int turno) {
        this.turno = turno;
    }
    private static ArrayList<HoraExtra> _listaHoraExtra = new ArrayList<HoraExtra>();

    public ArrayList<HoraExtra> getListaHoraExtra() {
        return _listaHoraExtra;
    }   

    public void avanzarP(int tiempo, ArrayList<Pedido> pedidos) {
        float dist = _velocidad * tiempo/60;
        int numNodos = Math.round(dist);
        float residuo = dist - numNodos;
        _residuo += residuo;
        int nodoExtra= Math.round(_residuo);
        _residuo-=nodoExtra;
        numNodos+=nodoExtra;
        int posActual = _posEnRuta;
        int posFin = posActual+numNodos;
        for(int i = posActual+1; i< posFin && i<_ruta.size();i++){
            _posicionActual = _ruta.get(i);
            _posEnRuta++;
            actualizaOrdenesP(_posicionActual,pedidos);
            this._gasolinaActual -= numNodos;
        }
    }

    private void actualizaOrdenesP(Punto p, ArrayList<Pedido> pedidos) {
        Reloj reloj = Reloj.getInstancia();
        if(p == Mapa.getAlmacen()){
            _gasolinaActual = _gasolinaTotal;
            _capacidadActual = _capacidadTotal;
            
            int turno = reloj.getTurnoActual();
            
            if (turno > this.getTurno()||((turno == 1)&&(this.getTurno()==3))){
                HoraExtra he = new HoraExtra(this);
                he.setFecha(reloj.getFecha());
                he.calcularHorasExtras();
                GestorVehiculos.getInstancia().getHorasExtras().add(he);
            }
            
            return;
        }
        for(int i =0; i< _listaPedido.size();i++){
            Pedido pedido = _listaPedido.get(i);
            if(pedido.getDestino()==p){//punto del pedido igual al punto del vehiculo
                if(pedido.getDemanda() > this.getCapacidadActual()){//la capacidad del vehiculo es menor a la cantidad de paquetes del pedido
                    pedido.setDemanda(pedido.getDemanda()-this.getCapacidadActual());
                    this.setCapacidadActual(0);
                }
                else{
                    this.setCapacidadActual(this.getCapacidadActual()-pedido.getDemanda());
                    pedido.setDemanda(0);
                    _listaPedido.remove(pedido);
                    pedidos.remove(pedido);
                }
            }
        }
    }

    public Calendar getFinTurno() {
        return finTurno;
    }

    public void setFinTurno(Calendar finTurno) {
        this.finTurno = finTurno;
    }

    public boolean tienePedidoPrioridad(int prioridad) {
        long horaActual = Reloj.getInstancia().getFecha().getTimeInMillis();
        long fechaVenc,tiempoRestante;
        for(Pedido pedido:_listaPedido){
            if (pedido.getPrioridad() == prioridad){
                fechaVenc = pedido.getFechaVencimiento().getTimeInMillis();
                tiempoRestante = (fechaVenc - horaActual)/1000/60;
                //if (tiempoRestante >= 80)
                    return true;
            }
        }
        return false;
    }

    public void desactivar() {
        Incidencia incidencia = new Incidencia(this);
        GestorVehiculos.getInstancia().getIncidencias().add(incidencia);
        GestorVehiculos.getInstancia().getIncidenciasActuales().add(incidencia);
        Reloj reloj = Reloj.getInstancia();
        incidencia.setFecha((Calendar)reloj.getFecha().clone());
        incidencia.calcularTiempoPerdido();
        this.disponible = false;
    }

    public void calcularLlegada(Pedido pedido) {
        int i;
        for (i = 0; i < this._ruta.size(); i++){
            if (this._ruta.get(i).getX() == pedido.getDestino().getX() && this._ruta.get(i).getY() == pedido.getDestino().getY() ){
                break;
            }
        }
        i++;
        int tiempoLlegada = i*60/_velocidad;
        pedido.setTiempoEstimadoLlegada(tiempoLlegada);
    }
}
